package liujia.bt.display.base
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import liujia.bt.display.BtDisplay;
	import liujia.bt.display.base.vo.ListenerVO;
	import liujia.bt.display.core.BtAnalyse;
	import liujia.bt.display.core.BtFrame;
	import liujia.bt.display.core.BtRun;
	import liujia.bt.display.interf.IBtMovieClip;
	import liujia.bt.display.interf.IBtTransform;
	import liujia.bt.util.ArrayUtils;
	
	
	/**
	 * BtAnimLite
	 * @author 刘佳 liujia08@snda.com
	 * $Id: BtAnimLite.as 2 2011-10-31 01:46:19Z sigmaliu@163.com $
	 * @version 1.0
	 */
	public class BtAnimLite extends Bitmap implements IBtMovieClip
	{
		protected var _registerPointType:int = 1;
		/**
		 *注册点类型 0左上角00点 1与mc一致（默认） 2中心点, 可随时改变这个值
		 * @return 
		 * 
		 */		
		public function get registerPointType():int {
			return _registerPointType;
		}
		/**
		 *注册点类型 0左上角00点 1与mc一致（默认） 2中心点, 可随时改变这个值
		 * @return 
		 * 
		 */		
		public function set registerPointType(value:int):void {
			_registerPointType = value;
			updateXYchange();
		}
		
		protected var _btFrameVec:Vector.<BtFrame> = null;
		/**
		 *每一帧BtFrame的集合 
		 * @return 
		 * 
		 */		
		public function get btFrameVec():Vector.<BtFrame> {
			return _btFrameVec;
		}
		/**
		 *每一帧BtFrame的集合 
		 * @return 
		 * 
		 */	
		public function set btFrameVec(value:Vector.<BtFrame>):void {
			_btFrameVec = value;
			_totalFrames = _btFrameVec.length;
		}
		
		protected var _totalFrames:int = 0;
		/**
		 *[只读 (read-only)] 全部帧的数量，也可以理解为最后一帧的序号 
		 * @return 
		 * 
		 */		
		public function get totalFrames():int {
			return _totalFrames;
		}
		public function set totalFrames(value:int):void {
			_totalFrames = value;
		}
		
		protected var _currentFrame:int = 1;
		/**
		 *[只读 (read-only)] 当前帧的序号，第一帧的序号从1开始，以此类推 
		 * @return 
		 * 
		 */		
		public function get currentFrame():int {
			return _currentFrame;
		}
		public function set currentFrame(value:int):void {
			_currentFrame = value;
		}
		
		protected var _rect:Rectangle = null;
		/**
		 *[只读 (read-only)] 当前帧的rect，提供了注册点信息和长宽
		 * @return 
		 * 
		 */		
		public function get rect():Rectangle {
			return _rect;
		}
		public function set rect(value:Rectangle):void {
			_rect = value;
		}
		
		protected var _isPlaying:Boolean = false;
		/**
		 *[只读 (read-only)] 是否正在播放 
		 * @return 
		 * 
		 */		
		public function get isPlaying():Boolean {
			return _isPlaying;
		}
		public function set isPlaying(value:Boolean):void {
			_isPlaying = value;
		}
		
		public var _currentBtFrame:BtFrame = null;
		/**
		 *当前的帧BtFrame 
		 * @return 
		 * 
		 */		
		public function get currentBtFrame():BtFrame {
			return _currentBtFrame;
		}
		public function set currentBtFrame(value:BtFrame):void {
			_currentBtFrame = value;
		}
		
		
		
		/**
		 *构造函数 
		 * @param bitmapData
		 * @param pixelSnapping
		 * @param smoothing
		 * 
		 */		
		public function BtAnimLite(bitmapData:BitmapData=null, pixelSnapping:String="auto", smoothing:Boolean=false)
		{
			super(bitmapData, pixelSnapping, smoothing);
		}
		
		/**
		 *从当前帧开始播放 
		 * 
		 */		
		public function play():void {
			BtRun.addBtMovieClip(this);
			_isPlaying = true;
		}
		
		/**
		 *停止播放，当前帧不变 
		 * 
		 */		
		public function stop():void {
			BtRun.removeBtMovieClip(this);
			_isPlaying = false;
		}
		
		/**
		 *跳到某一帧开始播放
		 * @param frame 帧序号，从1开始
		 * @param scene 没用的参数
		 * 
		 */		
		public function gotoAndPlay(frame:Object, scene:String=null):void {
			(frame < 1) && (frame = 1);
			_currentFrame = int(frame);
			_isPlaying || play();
		}
		
		/**
		 *跳到某一帧并停止播放
		 * @param frame 帧序号，从1开始
		 * @param scene 没用的参数
		 * 
		 */		
		public function gotoAndStop(frame:Object, scene:String=null):void {
			_isPlaying && BtRun.removeBtMovieClip(this);
			(frame < 1) && (frame = 1);
			(frame > _totalFrames) && (frame = _totalFrames);
			_currentFrame = int(frame);
			_isPlaying = false;
			
			_currentBtFrame = _btFrameVec[_currentFrame-1];
			render();
		}
		
		/**
		 *跳到下一帧并停止 
		 * 
		 */		
		public function nextFrame():void {
			gotoAndStop(++_currentFrame);
		}
		
		/**
		 *跳到上一帧并停止 
		 * 
		 */		
		public function prevFrame():void {
			gotoAndStop(--_currentFrame);
		}
		
		//缓存的BtFrame，用于判断是否需要渲染当前帧
		protected var tempBtFrame:BtFrame;
		/**
		 *由BtRun驱动的方法, 播放就是这个方法实现的 
		 * 
		 */		
		public function enterFrame():void {
			if (!_isPlaying) return;
			if (++_currentFrame > _totalFrames) _currentFrame = 1;
			
			tempBtFrame = _btFrameVec[_currentFrame-1];
			if (tempBtFrame != _currentBtFrame) {
				_currentBtFrame = tempBtFrame;
				render();
			}
		}
		
		/**
		 *外部对x设置的值 
		 */		
		protected var set_x:Number;
		/**
		 *外部对y设置的值 
		 */	
		protected var set_y:Number;
		/**
		 *渲染 
		 * 
		 */		
		protected function render():void {
			_rect = _currentBtFrame.rect;
			bitmapData = _currentBtFrame.bitmapData;
			updateXY();
		}
		
		/**
		 *更新坐标的方法，为了减少各种判断以提高效率 
		 */		
		protected var updateXY:Function = updateXY_MC;
		
		/**
		 *注册点与mc一致情况下的更新坐标方式 
		 * 
		 */		
		protected function updateXY_MC():void {
			super.x = superX = set_x + _rect.x;
			super.y = superY = set_y + _rect.y;
		}
		
		/**
		 *注册点与mc一致，且有缩放或旋转情况下的更新坐标方式 
		 * 
		 */
		protected function updateXY_MC_rotation():void {
			var p:Point = new Point(-super.scaleX*_rect.x, -super.scaleY*_rect.y);
			var angle:Number = Math.atan2(p.y, p.x) * BtAnalyse.radians2rotation;
			var regPoint:Point = Point.polar(p.length, -(angle+super.rotation) * BtAnalyse.rotation2radians);
			super.x = superX = set_x - regPoint.x;
			super.y = superY = set_y + regPoint.y;
		}
		
		/**
		 *注册点在中心点情况下的更新坐标方式 
		 * 
		 */
		protected function updateXY_CENTER():void {
			super.x = superX = set_x - _rect.width/2;
			super.y = superY = set_y - _rect.height/2;
		}
		
		/**
		 *注册点在中心点，且有缩放或旋转情况下的更新坐标方式 
		 * 
		 */
		protected function updateXY_CENTER_rotation():void {
			var p2:Point = new Point(super.scaleX*_rect.width/2, super.scaleY*_rect.height/2);
			var angle2:Number = Math.atan2(p2.y, p2.x) * BtAnalyse.radians2rotation;
			var regPoint2:Point = Point.polar(p2.length, -(angle2+super.rotation) * BtAnalyse.rotation2radians);
			super.x = superX = set_x - regPoint2.x;
			super.y = superY = set_y + regPoint2.y;
		}
		
		/**
		 *注册点在00点情况下的更新坐标方式 
		 * 
		 */		
		protected function updateXY_00():void {
			super.x = superX = set_x;
			super.y = superY = set_y;
		}
		
		/**
		 *父类的x坐标，即实际显示图像的左上角00点坐标 
		 */		
		internal var superX:Number = 0;
		/**
		 *父类的y坐标，即实际显示图像的左上角00点坐标 
		 */	
		internal var superY:Number = 0;
		
		/**
		 *实际显示图像的左上角00点坐标
		 * @return 
		 * 
		 */		
		public function get o_x():Number {
			return super.x;
		}
		/**
		 *实际显示图像的左上角00点坐标
		 * @return 
		 * 
		 */
		public function get o_y():Number {
			return super.y;
		}
		
		/**
		 *x坐标，与注册点类型相关
		 * @return 
		 * 
		 */		
		override public function get x():Number {
			return set_x;
		}
		/**
		 *x坐标，与注册点类型相关
		 * @return 
		 * 
		 */
		override public function set x(value:Number):void {
			set_x = Math.round(value);
			updateXY();
		}
		
		/**
		 *y坐标，与注册点类型相关
		 * @return 
		 * 
		 */
		override public function get y():Number {
			return set_y;
		}
		/**
		 *y坐标，与注册点类型相关
		 * @return 
		 * 
		 */
		override public function set y(value:Number):void {
			set_y = Math.round(value);
			updateXY();
		}
		
		/**
		 *旋转角度
		 * @return 
		 * 
		 */
		override public function get rotation():Number {
			return super.rotation;
		}
		/**
		 *旋转角度
		 * @return 
		 * 
		 */
		override public function set rotation(value:Number):void {
			super.rotation = value;
			updateXYchange();
			updateXY();
		}
		
		/**
		 *水平缩放 
		 * @return 
		 * 
		 */		
		override public function get scaleX():Number {
			return super.scaleX;
		}
		/**
		 *水平缩放 
		 * @return 
		 * 
		 */
		override public function set scaleX(value:Number):void {
			super.scaleX = value;
			updateXYchange();
			updateXY();
		}
		
		/**
		 *垂直缩放 
		 * @return 
		 * 
		 */		
		override public function get scaleY():Number {
			return super.scaleY;
		}
		/**
		 *垂直缩放 
		 * @return 
		 * 
		 */
		override public function set scaleY(value:Number):void {
			super.scaleY = value;
			updateXYchange();
			updateXY();
		}
		
		/**
		 *宽 
		 * @return 
		 * 
		 */		
		override public function get width():Number {
			return super.width;
		}
		
		/**
		 *宽 
		 * @return 
		 * 
		 */
		override public function set width(value:Number):void {
			super.width = value;
			updateXYchange();
			updateXY();
		}
		
		/**
		 *高
		 * @return 
		 * 
		 */
		override public function get height():Number {
			return super.height;
		}
		
		/**
		 *高
		 * @return 
		 * 
		 */
		override public function set height(value:Number):void {
			super.height = value;
			updateXYchange();
			updateXY();
		}
		
		/**
		 *更新坐标计算方式 
		 * 
		 */		
		protected function updateXYchange():void {
			switch (_registerPointType) {
				case BtDisplay.REGISTER_POINT_MC:
					updateXY = ((super.rotation==0 && super.scaleX==1 && super.scaleY==1) ? updateXY_MC : updateXY_MC_rotation);
					break;
				case BtDisplay.REGISTER_POINT_CENTER:
					updateXY = ((super.rotation==0 && super.scaleX==1 && super.scaleY==1) ? updateXY_CENTER : updateXY_CENTER_rotation);
					break;
				default:
					updateXY = updateXY_00;
					break;
			}
		}
		
		/**
		 *所有的监听器vo <ListenerVO> 
		 */		
		public var listenerVOArr:Array = [];
		/**
		 *添加监听 
		 * @param type
		 * @param listener
		 * @param useCapture
		 * @param priority
		 * @param useWeakReference
		 * 
		 */		
		override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
			listenerVOArr.push(new ListenerVO(type, listener, useCapture, priority, useWeakReference));
			super.addEventListener(type, listener, useCapture, priority, useWeakReference);
		}
		
		/**
		 *移除监听 
		 * @param type
		 * @param listener
		 * @param useCapture
		 * 
		 */		
		override public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void {
			ArrayUtils.delElement(listenerVOArr, {type:type, listener:listener, useCapture:useCapture});
			super.removeEventListener(type, listener, useCapture);
		}
		
		/**
		 *清除所有监听 
		 * 
		 */		
		public function clearListeners():void {
			for each (var vo:ListenerVO in listenerVOArr) {
				super.removeEventListener(vo.type, vo.listener, vo.useCapture);
				vo.destroy();
			}
			listenerVOArr.length = 0;
		}
		
	}
}
